.H TypeScript 1
.TD Sort these notes
.BL
TypeScripts uses static type checking 
instead of its dynamic variety applied by javascript.
.BL
There are two layers to TypeScript:
a dynamic layer,
pertaining to the code that gets traspiled to Javascript;
and a static layer,
which is the code related to types interpreted by TypeScript.
.BL
TypeScript supports all Javascript types
and adds two more: Array,
which can be either a list or a tuple
(array with fixed length), and any.
Null and undefined values must be explicitly allowed via the union
.CW | ) (
operator. For example:
.CBS Allowing null or undefined types in TypeScript
let maybeNumber : number | undefined | null = null;
.CBE
.BL
TypeScript is structuraly typed.
Therefore,
all objects with the same structure as the defined one
will be treated as equal.
.BL
You can have generics in TypeScript:
.CBS Simple example of a generic interface.
interface ValueContainer<Value> {
  value: Value;
}

type StringContainer = ValueContainer<string>;
.CBE
Anything in between the angle brakects
.CW <> ) (
are seen as parameters for the types.
Any valid Javascript name can be used as parameter identifers,
although,
commonly people like to use uppercase letters
(I, T, U, etc).
.BL
The type
.CW unknown
is similar no
.CW any ,
but requires that you do type narrowing
before operating with the value.
.CBS Narrowing an unknown value type.
function test(val: unknown)  {
	let str:string = null;
	if (typeof val === number) {
		str = "is a number"
	}
	return str
}
.CBE
Here,
we are using a typeguard so TypeScript can derive the value's type.
But narrowing also can be done using type assertions
and assertion functions.
.BL
You can group value together with
.CW enum ,
but there is very little reason to use them over interfaces
or type unions
(possibly with literal types)
instead.
.CBS Enum example.
enum NoYes {
  No = 'No',
  Yes = 'Yes',
}
.CBE
Passing a enum type instead of its value,
will make the function only accept the enum object.
.CBS Type issue with enums.
function func(x: NoYes.No) {
  return x;
}

func(NoYes.No); // Ok

func('No'); // Throws an error
.CBE
Instead of enums, prefer interfaces:
.CBS Example of a interface.
interface myExample {
	str?: String; // Optional value
	number10: 10;
	literalStr: "String literal";
}
.CBE
Or unions:
.CBS TypeScript unions with and without \f[CW]typeof\f[].
type one = 1 | '1' | 'one';

// Using typeof
const off = Symbol('off');
const info = Symbol('on');

// The infered type will be 'unique symbol'
type state =
  | typeof on
  | typeof off
;
.CBE
.TD Add tackling TypeScript syntax trees example
.BL
Since TypeScript's is structuraly typed
(that is,
doesn't discern between two different types with the same values),
we use discriminated unions to differ them.
.CBS TypeScript discriminated unions.
interface TemperatureCelsius {
  type: 'TemperatureCelsius',
  value: number,
}
interface TemperatureFahrenheit {
  type: 'TemperatureFahrenheit',
  value: number,
}

type Temperature = TemperatureCelsius | TemperatureFahrenheit;
.CBE
Notice the
.CW type
value inside the interface.
That is commonly called the
.I tag ,
it is used to differentiate
(thus discriminate)
between the types.
.BL
TypeScript allows excess properties when using interfaces,
but not when using object literals.
.CBS Excess properties example.
interface Point {
	x: number;
	y: number;
}

function printPoint(point: Point) {
	// ...
}

printPoint({ x: 5, y: 2, z: 3 }); // Ok

function printPoint2({ x: number, y: number }) {
	// ...
}
printPoint2({ x: 5, y: 2, z: 3 }); // Throws an error
.CBE
.BL
TypeScript doesn't always infers the type of an array properly,
due to the many ways an array with mixed types can be typed.
Further,
TypeScript doesn't infer treat array literals as tuples.
.CBS Improper array type inference in TypeScript.
function func(p: [number, number]) {
  return p;
}

// Treats pair as a array of numbers (number[])
const pair = [1, 2];

// Throws an error because TypeScript is expecting a tuple
// of two numbers ([number, number])
func(pair);
.CBE
.BL
Also,
TypeScript always assumes array indices are within bounds,
leading to improper typing.
.CBS TypeScript weird behaviour with out of bound indices in arrays
const messages: string[] = ['Hello'];

// Infered type is string when it should be undefined|string
const message = messages[3];
.CBE
Though,
tuples show expected behaviour.
.H "Basics"
.CBS Usual TypeScript project structure
TypeScript-project/
  dist/
  ts/
    src/
      main.ts
      util.ts
    test/
      util_test.ts
  tsconfig.json
.CBE
.BL
Enable all the strict compiling option for
.CW tsc
using the
.CW --strict
flag. It you can also granularly enable the strict options.
.H "Basic syntax"
.PP
The general syntax for type annotation is
.CW "whatever: Type" .
.CBS Assigning types in TypeScript.
let str: string = "This a string";
let num: Number = 42;

function typedFunc(str: string, num: number): String {
	return `This are my parameters: ${ string } ${ num }.`;
}
.CBE
.PP
But types can be inferred based on values,
both for functions and variables.
.CBS TypeScript type inference for variables and functions.
// TypeScript knows this is a string.
let str = "This a string";

// TypeScript can infer that the sum of two numbers must also be a number
function inferFunc(a: number, b: number) {
	return a + b
}
.CBE
.PP
It can also infer the type of anonymous functions
in a process know as
.I "contextual typing" .
.CBS TypeScript type inference in anonymous functions.
names.forEach((s) => {
  console.log(s.toUpperCase());
});
.CBE
.PP
It will use the type of the array  names together with the types of
.CW forEach
to figure out the type of
.CW s .
.H "Dealing with null and undefined"
\# as keyword, narrowing and literal types
.
.H "Tooling"
\# noImplicitAny and strictNullChecks
.
.H "The unexpected"
.TD Explain why this code is unsound
.CBS Unsound TypeScript code example.
const x: {f: string} = {f: "hi"};
const y: {f: number | boolean} = {f: 42};

var z;
if (Math.random() < 0.5) {
  z = x;
} else {
  z = y;
}

if (typeof(z.f) === "number") {
  z.f = "broken";
} else {
  z.f = 111;
}

console.log(z);
.CBE
.
.TD Explain structural inheritance
.CBS Structural inheritance in TypeScript.
interface Dog{}
interface Duck{}
function cook(d: Duck) {}
const spot: Dog = {}
cook(spot)
.CBE
.
.H "Best practices"
.H "Abusing the type system"
.H "Interfaces and type aliases"
